package com.xyyl.patient.controller;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayBaseRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.google.common.collect.Maps;
import com.xyyl.patient.common.utils.CalculateAgeUtils;
import com.xyyl.patient.common.utils.SysConfigUtils;
import com.xyyl.patient.core.constant.AppEnum;
import com.xyyl.patient.core.controller.BaseController;
import com.xyyl.patient.core.util.ResponseBodyResult;
import com.xyyl.patient.core.util.RestClient;
import com.xyyl.patient.entity.base.NotificationEntity;
import com.xyyl.patient.entity.doctor.Doctor;
import com.xyyl.patient.entity.order.SpeedPhoneOrder;
import com.xyyl.patient.service.doctor.DoctorService;
import com.xyyl.patient.service.order.SpeedPhoneOrderService;

/**
 * @projectName:xyyl-patient-web
 * @ClassName: SpeedPhoneOrderController
 * @Description: 极速电话订单Controller
 * @author chens
 * @date 2018年1月2日
 *
 */
@RestController
@RequestMapping("/speedPhoneOrder")
public class SpeedPhoneOrderController extends BaseController {

	private Logger logger = LogManager.getLogger(SpeedPhoneOrderController.class);

	@Autowired
	private SpeedPhoneOrderService speedPhoneOrderService;

	@Autowired
	private DoctorService doctorService;

	@Autowired
	private WxPayService payService;

	@Value("#{weixin['common.domain']}")
	private String domain;

	/**
	 * @Title: submitOrder
	 * @Description: 提交订单
	 * @param @param consultOrder
	 * @param @return    参数
	 * @return JSONObject    返回类型
	 * @throws
	 */
	@RequestMapping(value = "/submitOrder", method = RequestMethod.POST)
	public JSONObject submitOrder(@RequestBody SpeedPhoneOrder speedPhoneOrder) {

		logger.info("---submit  speedPhoneOrder---");
		try {
			if (speedPhoneOrder != null) {
				speedPhoneOrder.setStatus(AppEnum.common.Pay_status_not.getValue());
			}

			/** 取系统默认的订单价格**/
			if (speedPhoneOrder.getOrderAmount() == null) {
				String defaultOrderAmount = SysConfigUtils
						.getConfigValue(AppEnum.sysConfig.OMS_SYSTEM_SPEED_ORDER_PRICE.name());
				if (defaultOrderAmount != null) {
					BigDecimal orderAmount = new BigDecimal(defaultOrderAmount);
					speedPhoneOrder.setOrderAmount(orderAmount);
				}
				if(speedPhoneOrder.getBirthday()!=null){
				   speedPhoneOrder.setAge(CalculateAgeUtils.getAge(speedPhoneOrder.getBirthday()));	
				}
			}
			return ResponseBodyResult.success("下单成功", speedPhoneOrderService.insertSpeedPhoneOrder(speedPhoneOrder));

		} catch (Exception e) {
			return ResponseBodyResult.error("下单失败", e);
		}
	}

	/**
	 * @Title: queryOrderDetailById
	 * @Description: 订单明细查询
	 * @param @param id
	 * @param @return    参数
	 * @return JSONObject    返回类型
	 * @throws
	 */
	@RequestMapping(value = "/queryOrderDetailById", method = RequestMethod.GET)
	public JSONObject queryOrderDetailById(@RequestParam Long id) {

		logger.info(" query order:{}", id);
		try {
			Map<String, Object> paramMap = Maps.newHashMap();
			paramMap.put("id", id);
			SpeedPhoneOrder speedPhoneOrder = speedPhoneOrderService.queryObject(paramMap);
			return ResponseBodyResult.success(speedPhoneOrder);
		} catch (Exception e) {
			return ResponseBodyResult.error("订单明细查询失败!", e);
		}
	}

	/**
	 * @Title: confirmPay
	 * @Description: 确认支付
	 *  一、微信支付：1.调用微信统一下单接口，返回JSSDKPayInfo相关的信息
	 * @return  返回类型 
	 * @throws
	 */
	@RequestMapping(value = "/confirmPay", method = RequestMethod.POST)
	public JSONObject confirmPay(@RequestParam Long orderId) {

		logger.info("---confirmPay  payOrder---");
		try {
			Map<String, Object> paramMap = Maps.newHashMap();
			paramMap.put("id", orderId);
			SpeedPhoneOrder speedPhoneOrderEntity = speedPhoneOrderService.queryObject(paramMap);
			if (speedPhoneOrderEntity.getStatus().equals(AppEnum.common.Pay_status_confirm.getValue())) {
				return ResponseBodyResult.fail("该订单已支付，请勿重复提交!");
			}
			if (speedPhoneOrderEntity.getStatus().equals(AppEnum.common.Prder_status_refund_finish.getValue())) {
				return ResponseBodyResult.fail("该订单已过期，系统已自动退款!");
			}
			return submitWxPay(speedPhoneOrderEntity);

		} catch (Exception e) {

			return ResponseBodyResult.error("订单提交支付失败!", e);
		}
	}

	/**
	 * @Title: submitWxPay
	 * @Description:提交微信统一下单
	 * @param  consultOrder
	 * @param  参数
	 * @return JSONObject  返回类型
	 * @throws
	 */
	private JSONObject submitWxPay(SpeedPhoneOrder speedPhoneOrder) {
		/** 组装参数信息 **/
		WxPayUnifiedOrderRequest prepayInfo = WxPayUnifiedOrderRequest.newBuilder().openid(speedPhoneOrder.getOpenId())
				.outTradeNo(speedPhoneOrder.getOrderSn())
				.totalFee(WxPayBaseRequest.yuanToFee(String.valueOf(speedPhoneOrder.getOrderAmount()))).body("极速订单支付")
				.spbillCreateIp("192.168.0.1").notifyURL(domain + "/speedPhoneOrder/orderPayCallback").build();

		/** 提交微信统一下单 **/
		Map<String, String> payInfos = Maps.newHashMap();
		try {
			payInfos = this.payService.getPayInfo(prepayInfo);
			if (payInfos != null && payInfos.get("package") != null) {
				return ResponseBodyResult.success("提交成功", payInfos);
			} else {
				return ResponseBodyResult.fail("统一下单失败");
			}
		} catch (WxPayException e) {
			return ResponseBodyResult.error("统一下单失败", e);
		}

	}

	/**
	 * @Title: orderPayCallback
	 * @Description: 微信通知支付结果的回调并更新订单信息
	 * @param  request
	 * @param  response
	 * @param  参数
	 * @return String    返回类型
	 * @throws
	 */
	@RequestMapping(value = "/orderPayCallback", method = RequestMethod.POST)
	public String orderPayCallback(HttpServletRequest request, HttpServletResponse response) {

		logger.info("---callback  payOrder---");
		try {
			synchronized (this) {
				/** 解析支付结果 **/
				String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
				WxPayOrderNotifyResult result = payService.parseOrderNotifyResult(xmlResult);
				if (AppEnum.common.Pay_result_success.getName().equals(result.getReturnCode())) {
					if (AppEnum.common.Pay_result_success.getName().equals(result.getResultCode())) {

						/** 支付成功，处理业务数据 **/
						String orderId = result.getOutTradeNo();
						String ordersn = result.getTransactionId();
						Map<String, Object> paramMap = Maps.newHashMap();
						paramMap.put("orderSn", orderId);
						SpeedPhoneOrder speedPhoneOrder = speedPhoneOrderService.queryObject(paramMap);
						if (speedPhoneOrder.getStatus().equals(AppEnum.common.Pay_status_not.getValue())) {
							SpeedPhoneOrder speedPhoneOrderVo = new SpeedPhoneOrder();
							speedPhoneOrderVo.setId(speedPhoneOrder.getId());
							speedPhoneOrderVo.setTransactionId(ordersn);
							speedPhoneOrderVo.setPayType(AppEnum.common.Order_payType_wx.getValue());
							speedPhoneOrderService.confirmPayOrder(speedPhoneOrderVo);
						}
						
						sendMessage();
						
						return WxPayNotifyResponse.success("ok");
					} else {
						return WxPayNotifyResponse.fail("result_code is FAIL");
					}
				} else {
					return WxPayNotifyResponse.fail("check signature FAIL");
				}

			}
		} catch (Exception e) {
			return WxPayNotifyResponse.fail("http request FAIL");
		}

	}

	/**
	 * @Title: sendMessage
	 * @Description:发送推送消息
	 * @param @param doctorid    参数
	 * @return void    返回类型
	 * @throws
	 */
	public void sendMessage() {

		logger.info("--- push message---");
		
		Executors.newSingleThreadExecutor().execute(new Runnable() {
			@Override
			public void run() {
				NotificationEntity notificationEntity = null;
				try {
					/**查询已开通极速电话的医生集合**/
					List<Doctor> doctors = doctorService.queryDoctorListOfSpeedPhoneOrder();
					if (doctors != null && !doctors.isEmpty()) {
						Long[] idsArr = new Long[doctors.size()];
						int index = 0;
						for (Doctor doctor : doctors) {
							idsArr[index] = doctor.getId().longValue();
						}
						String activity = SysConfigUtils
								.getConfigValue(AppEnum.sysConfig.OMS_SPEEDPHONE_ORDER_ANDROID_ACTIVITY.name());
						String push_api_url = SysConfigUtils
								.getConfigValue(AppEnum.sysConfig.OMS_PHONE_ORDER_PUSH_API_URL.name());

						notificationEntity = new NotificationEntity("极速电话订单", "您有一条极速电话订单，点击查看", activity);
						notificationEntity.setDoctorIds(idsArr);
						notificationEntity.setBusinessType(AppEnum.common.Order_consumetype_speedPhone.getValue());

						RestClient.postForObject(push_api_url, JSON.toJSONString(notificationEntity), String.class);
					}
				} catch (Exception e) {
					logger.error("推送失败:" + e);
				}

				
				
			}
		});
		
	}
	
}
